#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "utilidades.h"
#include "termino.h"
#include "../tda/lista/lista.h"

/*
 * Función auxiliar para imprimir si estuvo OK o no.
 */
void print_test(char* name, bool result){
    printf("%s: %s\n", name, result? "OK" : "ERROR");
}

void wrapper_destruir_termino (void* termino){
	termino= (termino_t*)termino;
	termino_destruir(termino);
}

void prueba_leer_de_lineas_de_archivo_de_texto(){
	
	char* ruta_archivo_de_prueba = "prueba";
	
	FILE* archivo=fopen(ruta_archivo_de_prueba,"w");
	fprintf(archivo,"Esta es una linea de prueba\n");
	fprintf(archivo,"Esta es otra linea de prueba\n");
	fclose(archivo);
	
	archivo=fopen(ruta_archivo_de_prueba,"r");
	
	char* linea=leer_linea(archivo);
	print_test("Prueba leer una linea al principio",strcmp(linea,"Esta es una linea de prueba")==0);
	cadena_destruir(linea);

	linea=leer_linea(archivo);
	print_test("Prueba leer una linea en el medio",strcmp(linea,"Esta es otra linea de prueba")==0);
	cadena_destruir(linea);

	fclose(archivo);
	remove(ruta_archivo_de_prueba);
	
}


void prueba_estructura_terminos(){
	printf("\n----Pruebas de termino_t*----\n");
	
	// Setup
	char* ruta_archivo_de_prueba = "prueba";
	FILE* archivo=fopen(ruta_archivo_de_prueba,"w");
	fprintf(archivo,"this is a great test line\n");
	fclose(archivo);
	
	// Arrange
	archivo=fopen(ruta_archivo_de_prueba,"r");
	char* linea = leer_linea(archivo);
	lista_t* lista_terminos = separar_cadena_en_terminos(linea,3,NULL);
	lista_iter_t* iter = lista_iter_crear(lista_terminos);
	char* resultado[]={	
						"this",
						"this is",
						"is",
						"a",
						"is a",
						"this is a",
						"great",
						"a great",
						"is a great",
						"test",
						"great test",
						"a great test",
						"line",
						"test line",
						"great test line"
						};
	
	int i=0;
	bool flag = true;
	while( !lista_iter_al_final(iter) ){
		termino_t* termino = (termino_t*)lista_iter_ver_actual(iter);
		if (strcmp(resultado[i++],termino->valor)!=0)
			flag = false;
		lista_iter_avanzar(iter);
	}
		
	print_test("Prueba partir string en terminos de a 3",flag);
	
	// Clean
	cadena_destruir(linea);
	lista_iter_destruir(iter);
	lista_destruir(lista_terminos,wrapper_destruir_termino);
	fclose(archivo);
	remove(ruta_archivo_de_prueba);

}


void prueba_linea_con_1_palabra_tomando_de_a_2(){
	
	// Setup
	char* ruta_archivo_de_prueba = "prueba";
	FILE* archivo=fopen(ruta_archivo_de_prueba,"w");
	fprintf(archivo,"this\nis a\nline");
	fclose(archivo);
	
	// Arrange
	archivo=fopen(ruta_archivo_de_prueba,"r");
	char* linea = leer_linea(archivo);
	lista_t* lista_terminos = separar_cadena_en_terminos(linea,5,NULL);
	lista_iter_t* iter = lista_iter_crear(lista_terminos);
	char* resultado[]={	
						"this",
						"this is",
						"is",
						"a",
						"is a",
						"this is a",
						"great",
						"a great",
						"is a great",
						"test",
						"great test",
						"a great test",
						"line",
						"test line",
						"great test line"
						};
	
	int i=0;
	bool flag = true;
	while( !lista_iter_al_final(iter) ){
		termino_t* termino = (termino_t*)lista_iter_ver_actual(iter);
		if (strcmp(resultado[i++],termino->valor)!=0)
			flag = false;
		lista_iter_avanzar(iter);
	}
		
	print_test("Prueba magica",flag);
	
	// Clean
	cadena_destruir(linea);
	lista_iter_destruir(iter);
	lista_destruir(lista_terminos,wrapper_destruir_termino);
	fclose(archivo);
	remove(ruta_archivo_de_prueba);

}

void prueba_leer_N_chars_sin_sobrante(){
	char* ruta_archivo_de_prueba = "prueba";
	
	FILE* archivo=fopen(ruta_archivo_de_prueba,"w");
	fprintf(archivo,"Esta\nes\nuna\nlinea\nde\nprueba\n");
	fprintf(archivo,"Esta es otra linea de prueba\n");
	fclose(archivo);
	
	archivo=fopen(ruta_archivo_de_prueba,"r");
	
	char* bloque=leer_bloque_string_de_archivo(archivo,3);
	print_test("Prueba leer un bloque de 3",strcmp(bloque,"Esta")==0);
	cadena_destruir(bloque);

	bloque = leer_bloque_string_de_archivo(archivo,4);
	print_test("Prueba leer un bloque con \\n de por medio",strcmp(bloque,"es\nuna")==0);
	cadena_destruir(bloque);
	fclose(archivo);
	remove(ruta_archivo_de_prueba);

}

void prueba_volumen(){
	char* ruta_archivo_de_prueba = "test";
	
	
	FILE* archivo=fopen(ruta_archivo_de_prueba,"w");
	fprintf(archivo,"auto:10\ncasa:11\ninconstitucionalmente:14\nlargo:10\npoder:140\nzorro:100\n");
	fclose(archivo);
	
	archivo=fopen(ruta_archivo_de_prueba,"r");
	
	char* bloque=leer_bloque_string_de_archivo(archivo,46);
	print_test("Prueba leer un bloque de 50 y pico",strcmp(bloque,"auto:10\ncasa:11\ninconstitucionalmente:14\nlargo:10")==0);
	cadena_destruir(bloque);
	
	fclose(archivo);
	remove(ruta_archivo_de_prueba);
	FILE* asd = fopen("mat","w");

	for (int i=0;i<1000000;i++){
		for(int j=0;j<1000;j++){
			int a = rand() % 100;
			if (a<2)
				fprintf(asd,"%d:%d",j,a);
		}
		fprintf(asd,"\n");	
	}
	fclose(asd);
}



void prueba_leer_de_a_bloques(){
	printf("\n----Pruebas de lectura en bloques----\n\n");

	prueba_leer_N_chars_sin_sobrante();
	prueba_volumen();


}


void prueba_utilidades(){
    prueba_leer_de_lineas_de_archivo_de_texto();
	prueba_linea_con_1_palabra_tomando_de_a_2();
    prueba_estructura_terminos();
    //prueba_leer_de_a_bloques();
}


int main (){
    prueba_utilidades();
    return 0;
}
